// 导入 threejs
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 导入lil.gui
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'

// 创建场景
const scene= new THREE.Scene()

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45,  // 视角
  window.innerWidth / window.innerHeight,
  0.1,  // 近平面
  1000   // 远平面
)

// 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)   // 整屏渲染，canvas为基础

// 将画布添加到页面标签里
document.body.appendChild(renderer.domElement)

// 添加世界坐标辅助器，x,y,z轴的辅助线
const axesHelper = new THREE.AxesHelper(5)   // 并设置线段的长度为5
// 添加到场景当中
scene.add(axesHelper)

// 设置相机位置
// camera.position.z = 5   // 设置在哪个轴， x, y, z 这里设置z轴
// camera.lookAt(0, 0, 0)    // 设置相机看向什么位置，看向原点位置

// 为了看到z轴的线，调整相机位置
camera.position.z = 5   
camera.position.x = 3
camera.position.y = 2
camera.lookAt(0, 0, 0)  

// 添加轨道控制器， 先在上面导入
const controls = new OrbitControls(camera, renderer.domElement)   // renderer.domElement这个表示监听的元素是 canvas 元素， 渲染的标签
// const controls = new OrbitControls(camera, document.body)   // 监听body
// 设置带阻尼的惯性，阻尼感
controls.enableDamping = true         // 开启
// 设置阻尼系数
// controls.dampingFactor = 0.01          // 越小阻尼感越大
controls.dampingFactor = 0.5
// controls.autoRotate = true         // 自转，自动绕着目标旋转， 开启这个必须要使用 controls方法

// 做一个渲染函数， 不断渲染
function animate() {
  controls.update()    // 渲染的时候也要每次更新控制器
  requestAnimationFrame(animate)       // 相当于定时器，不断调用，一直渲染
  // 旋转功能
  // cube.rotation.x += 0.01
  // cube.rotation.y += 0.01
  // 渲染
  renderer.render(scene, camera)
}
animate()

// 监听窗口变化
window.addEventListener("resize", () => {
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  // 更新相机投影矩阵 ， 一定要加
  camera.updateProjectionMatrix()
})

// 创建GUI
const gui = new GUI()

// 添加三个球
const sphere1 = new THREE.Mesh(
  new THREE.SphereGeometry(1, 32, 32),
  new THREE.MeshBasicMaterial({
    color: 0x0000ff,
  })
)
sphere1.position.x = -2      // 设置球的位置
scene.add(sphere1)

const sphere2 = new THREE.Mesh(
  new THREE.SphereGeometry(1, 32, 32),
  new THREE.MeshBasicMaterial({
    color: 0x00ffff,
  })
)
sphere2.position.x = 1      // 设置球的位置
scene.add(sphere2)

const sphere3 = new THREE.Mesh(
  new THREE.SphereGeometry(1, 32, 32),
  new THREE.MeshBasicMaterial({
    color: 0xffffff,
  })
)
sphere3.position.x = 4      // 设置球的位置
scene.add(sphere3)


// 创建射线
const raycaster = new THREE.Raycaster()
// 创建鼠标向量
const mouse = new THREE.Vector2()

// 点击事件，交互
window.addEventListener("click", (event) => {

  // 获取鼠标点击的位置
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1        // 转换成 -1~1之间的值
  mouse.y = 1 - (event.clientY / window.innerHeight) * 2
  
  // console.log(mouse.x, mouse.y);

  // 通过摄像机和鼠标位置更新射线
  raycaster.setFromCamera(mouse, camera)

  // 计算物体和射线的焦点，检测场景中的物体
  const intersects = raycaster.intersectObjects([sphere1, sphere2, sphere3])

  if(intersects.length > 0) {
    if(intersects[0].object._select) {
      intersects[0].object.material.color.set(intersects[0].object._originColor)
      intersects[0].object._select = false
      return
    }
    // 说明射线碰到了物体，变个色=
    intersects[0].object._select = true   // 设置一些自定义属性，用来判断
    intersects[0].object._originColor = intersects[0].object.material.color.getHex()  // 获取颜色的16进制的方法
    intersects[0].object.material.color.set(0x825c52)
  }

  console.log(intersects);
})